import tkinter as tk
import servletapi
import recognition
import request_queue
import cv2
import threading
import PIL.Image, PIL.ImageTk

cid = "" # 课程编号
passwd = "" # 管理密码
checkin_passwd = "" # 签到口令
faces_dir = "faces" # 存放已知人脸的目录

login_view = tk.Tk()

def login_wrapper():
    # 设定有关值
    global cid, passwd, checkin_passwd
    cid = entry_loginview_cid.get()
    passwd = entry_loginview_passwd.get()
    checkin_passwd = entry_loginview_checkin_passwd.get()
    try:
        if servletapi.login(cid, passwd):
            # 成功则销毁登录窗口并打开考勤窗口
            login_view.destroy()
        else:
            # 失败则显示错误信息
            label_loginview_error["text"] = "用户名或密码错误"
    except Exception as ex:
        label_loginview_error["text"] = "登录出错"

# 创建窗口布局
login_view.title("考勤助理登录")
label_loginview_cid = tk.Label(login_view, text="课程编号")
label_loginview_cid.grid(row=0, column=0)
entry_loginview_cid = tk.Entry(login_view)
entry_loginview_cid.grid(row=0, column=1)
label_loginview_passwd = tk.Label(login_view, text="管理密码")
label_loginview_passwd.grid(row=1, column=0)
entry_loginview_passwd = tk.Entry(login_view)
entry_loginview_passwd.grid(row=1, column=1)
label_loginview_checkin_passwd = tk.Label(login_view, text="签到口令")
label_loginview_checkin_passwd.grid(row=2, column=0)
entry_loginview_checkin_passwd = tk.Entry(login_view)
entry_loginview_checkin_passwd.grid(row=2, column=1)
button_login = tk.Button(login_view, text="登录", command=login_wrapper)
button_login.grid(row=3, column=0)
label_loginview_error = tk.Label(login_view, text="")
label_loginview_error.grid(row=3, column=1)

# 显示登录页面
login_view.mainloop()

# 加载人脸数据
faces, names = recognition.load_faces_from_dir(faces_dir)

# 初始化请求队列
checkin_req = request_queue.RequestQueue(daemon=True)
checkin_req.password = checkin_passwd

# 创建考勤页面
checkin_view = tk.Tk()
checkin_view.title("人脸考勤")
lable_checkinview_img = tk.Label()
lable_checkinview_img.grid(row=0, column=0)
lable_checkinview_msg = tk.Label(font=("", 30))
lable_checkinview_msg.grid(row=1, column=0)
tkimg = None

# 开启摄像头
cap = cv2.VideoCapture(0)

# OpenCV图像转Tk图像
def cv2tk(img):
    #转换颜色从BGR到RGBA
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGBA)
    #将图像转换成Image对象
    img = PIL.Image.fromarray(img)
    img = PIL.ImageTk.PhotoImage(image=img)
    return img

# 实现人脸考勤的主要逻辑
def checked_in_wrapper():
    global cap, checkin_req
    while True:
        success, img = cap.read()
        if success:
            # 显示画面
            global tkimg
            tkimg = cv2tk(img)
            lable_checkinview_img["image"] = tkimg
            # 对识别到的所有人脸进行考勤
            for sid in recognition.get_names_from_image(img, faces, names):
                checkin_req.add_checkin_request(sid)

def update_message():
    while True:
        msg = checkin_req.get_next_message()
        lable_checkinview_msg["text"] = msg

# 启动考勤逻辑
threading.Thread(target=checked_in_wrapper, daemon=True).start()
threading.Thread(target=update_message, daemon=True).start()
checkin_req.start()

# 显示考勤界面
checkin_view.mainloop()

# 关闭摄像头
cap.release()